import React, { useState, useEffect } from 'react';

const Calculator = () => {
  const [display, setDisplay] = useState(null);
  const [previousValue, setPreviousValue] = useState(null);
  const [operation, setOperation] = useState(null);
  const [shouldResetDisplay, setShouldResetDisplay] = useState(false);
  const [clickedButton, setClickedButton] = useState(null);

  useEffect(() => {
    if (clickedButton !== null) {
      const timer = setTimeout(() => setClickedButton(null), 100);
      return () => clearTimeout(timer);
    }
  }, [clickedButton]);

  const handleNumberInput = (num: number) => {
    if (display === 0 || shouldResetDisplay) {
      setDisplay(num);
      setShouldResetDisplay(false);
    } else {
      setDisplay(display + num);
    }
  };

  const handleOperationInput = (op: any) => {
    if (previousValue === null) {
      setPreviousValue(parseFloat(display));
    } else if (operation) {
      const result = performOperation();
      setPreviousValue(result);
      setDisplay(result.toString());
    }
    setOperation(op);
    setShouldResetDisplay(true);
  };

  const performOperation = () => {
    const prev = parseFloat(previousValue);
    const current = parseFloat(display);
    let result;
    switch (operation) {
      case '+': result = add(prev, current); break;
      case '-': result = subtract(prev, current); break;
      case '×': result = multiply(prev, current); break;
      case '÷': result = divide(prev, current); break;
      default: result = current;
    }
    return roundResult(result);
  };

  const getDecimalPlaces = (num) => {
    const match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
    if (!match) return 0;
    return Math.max(0, (match[1] ? match[1].length : 0) - (match[2] ? +match[2] : 0));
  };

  const add = (a, b) => {
    const precision = Math.max(getDecimalPlaces(a), getDecimalPlaces(b));
    return parseFloat((a + b).toFixed(precision));
  };

  const subtract = (a, b) => {
    const precision = Math.max(getDecimalPlaces(a), getDecimalPlaces(b));
    return parseFloat((a - b).toFixed(precision));
  };

  const multiply = (a, b) => {
    const precision = getDecimalPlaces(a) + getDecimalPlaces(b);
    return parseFloat((a * b).toFixed(precision));
  };

  const divide = (a, b) => {
    if (b === 0) return 'Error';
    const precision = Math.max(getDecimalPlaces(a), getDecimalPlaces(b));
    return parseFloat((a / b).toFixed(precision));
  };

  const roundResult = (num) => {
    if (typeof num === 'number') {
      // Limit to 10 decimal places to avoid very long results
      return parseFloat(num.toFixed(10));
    }
    return num;
  };

  const handleEquals = () => {
    if (operation && previousValue !== null) {
      const result = performOperation();
      setDisplay(result.toString());
      setPreviousValue(null);
      setOperation(null);
    }
  };

  const handleClear = () => {
    setDisplay('0');
    setPreviousValue(null);
    setOperation(null);
  };

  const handlePercent = () => {
    setDisplay((parseFloat(display) / 100).toString());
  };

  const handleToggleSign = () => {
    setDisplay((parseFloat(display) * -1).toString());
  };

  const handleDecimal = () => {
    if (!display.includes('.')) {
      setDisplay(display + '.');
    }
  };

  const buttonClass = (type, value) => {
    let baseClass = "rounded-full p-4 text-2xl transition-all duration-100 transform";
    if (clickedButton === value) {
      baseClass += " scale-90";
    }
    switch (type) {
      case 'number':
        return `${baseClass} bg-gray-700 text-white hover:bg-gray-600 active:bg-gray-500`;
      case 'operation':
        return `${baseClass} ${operation === value ? 'bg-white text-orange-500' : 'bg-orange-500 text-white'} hover:bg-orange-400 active:bg-orange-300`;
      case 'function':
        return `${baseClass} bg-gray-500 text-white hover:bg-gray-400 active:bg-gray-300`;
      default:
        return baseClass;
    }
  };

  const handleButtonClick = (value, type, action) => {
    setClickedButton(value);
    action(value);
  };

  return (
    <div className="calculator bg-gray-900 p-4 rounded-lg max-w-xs mx-auto">
      <div className="display text-right text-white text-5xl mb-4 h-20 flex items-end justify-end">
        <span className="truncate">{display}</span>
      </div>
      <div className="grid grid-cols-4 gap-2">
        <button onClick={() => handleButtonClick('C', 'function', handleClear)} className={buttonClass('function', 'C')}>C</button>
        <button onClick={() => handleButtonClick('±', 'function', handleToggleSign)} className={buttonClass('function', '±')}>±</button>
        <button onClick={() => handleButtonClick('%', 'function', handlePercent)} className={buttonClass('function', '%')}>%</button>
        <button onClick={() => handleButtonClick('÷', 'operation', handleOperationInput)} className={buttonClass('operation', '÷')}>÷</button>
        
        <button onClick={() => handleButtonClick('7', 'number', handleNumberInput)} className={buttonClass('number', '7')}>7</button>
        <button onClick={() => handleButtonClick('8', 'number', handleNumberInput)} className={buttonClass('number', '8')}>8</button>
        <button onClick={() => handleButtonClick('9', 'number', handleNumberInput)} className={buttonClass('number', '9')}>9</button>
        <button onClick={() => handleButtonClick('×', 'operation', handleOperationInput)} className={buttonClass('operation', '×')}>×</button>
        
        <button onClick={() => handleButtonClick('4', 'number', handleNumberInput)} className={buttonClass('number', '4')}>4</button>
        <button onClick={() => handleButtonClick('5', 'number', handleNumberInput)} className={buttonClass('number', '5')}>5</button>
        <button onClick={() => handleButtonClick('6', 'number', handleNumberInput)} className={buttonClass('number', '6')}>6</button>
        <button onClick={() => handleButtonClick('-', 'operation', handleOperationInput)} className={buttonClass('operation', '-')}>-</button>
        
        <button onClick={() => handleButtonClick('1', 'number', handleNumberInput)} className={buttonClass('number', '1')}>1</button>
        <button onClick={() => handleButtonClick('2', 'number', handleNumberInput)} className={buttonClass('number', '2')}>2</button>
        <button onClick={() => handleButtonClick('3', 'number', handleNumberInput)} className={buttonClass('number', '3')}>3</button>
        <button onClick={() => handleButtonClick('+', 'operation', handleOperationInput)} className={buttonClass('operation', '+')}>+</button>
        
        <button onClick={() => handleButtonClick('0', 'number', handleNumberInput)} className={`${buttonClass('number', '0')} col-span-2 text-left pl-8`}>0</button>
        <button onClick={() => handleButtonClick('.', 'number', handleDecimal)} className={buttonClass('number', '.')}>.</button>
        <button onClick={() => handleButtonClick('=', 'operation', handleEquals)} className={buttonClass('operation', '=')}>=</button>
      </div>
    </div>
  );
};

export default Calculator;
